水無瀬の部屋 > Programming > sample > tools > workthrd > traythrd.cpp |
---|
1: //*********************************************************
2: // プロジェクト: traythrd
3: // ファイル名: traythrd.cpp
4: //*********************************************************
5: #include <workthrd/traythrd.h>
6: #include <workthrd/workthrd.h>
7: #include <dlg/dyndlg.h>
8:
9:
10: //---------------------------------------------------------
11: // マクロ定数 の 定義
12: //---------------------------------------------------------
13: #define ID_TRAYICON ( 1 ) // システムトレイ・アイコン
14: #define IDT_WAITTHREAD ( 102 )
15: #define UM_ICONMESSAGE ( 1 + WM_APP ) // 0x8001
16: #define UM_MENUPOPUP ( 2 + WM_APP )
17: #define IDM_CANCEL ( 40000 )
18: #define PROP_TRAYICON "PROP_TRAYICON"
19: #define PROP_THREAD "PROP_THREAD"
20:
21:
22: //---------------------------------------------------------
23: // 構造体 の 宣言
24: //---------------------------------------------------------
25: // busyicon_t
26: typedef struct busyicon_tag
27: {
28: WorkerThreadProc_t proc;
29: void *param;
30: HICON hIcon;
31: const char *message;
32: } busyicon_t;
33:
34:
35: //---------------------------------------------------------
36: // ファイルスコープ関数 の 宣言
37: //---------------------------------------------------------
38: static INT_PTR CALLBACK BusyTrayDlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
39: static NOTIFYICONDATA *AddWorkingTrayIcon( HWND hWnd, UINT uID, UINT uMessage, HICON hIcon, const char *szTip );
40: static DLGTEMPLATE *CreateBusyTrayDialogTemplate( void );
41: static void CALLBACK WatchWorkerThreadProc( HWND hWnd, UINT, UINT uID, DWORD );
42: static thread_t *GetPropWorkerThread( HWND hWnd );
43:
44:
45: //*********************************************************
46: // RunOnTrayIcon
47: //*********************************************************
48: int
49: RunOnTrayIcon
50: (
51: WorkerThreadProc_t proc, // 実行関数
52: void *param, // 実行関数に渡す引数
53: HICON hIcon, // アイコン
54: const char *message // メッセージ
55: )
56: {
57: // パラメタの仮定
58: ASSERT( IsValidCodePtr( proc ) );
59: ASSERT( IsValidIconHandle( hIcon ) );
60: ASSERT( IsValidStringPtr( message ) );
61: ASSERT( strlen( message ) < numof( ((NOTIFYICONDATA *)null)->szTip ) );
62:
63: //
64: DLGTEMPLATE *templ = CreateBusyTrayDialogTemplate();
65: if ( ! templ )
66: {
67: return IDABORT;
68: }
69:
70: //
71: busyicon_t bi;
72: bi.proc = proc;
73: bi.param = param;
74: bi.hIcon = hIcon;
75: bi.message = message;
76:
77: //
78: const INT_PTR result = DialogBoxIndirectParam
79: (
80: GetModuleHandle( null ),
81: templ,
82: HWND_DESKTOP,
83: BusyTrayDlgProc,
84: reinterpret_cast<LPARAM>( &bi )
85: );
86:
87: //
88: VERIFY( DestroyDialogTemplate( templ ) );
89:
90: return _w64_static_cast<int>( result ); // [_W64]
91: }//RunOnTrayIcon
92:
93:
94: //******************************************************************************************************************
95: // private
96: //******************************************************************************************************************
97: //*********************************************************
98: // CreateBusyTrayDialogTemplate
99: //*********************************************************
100: static
101: DLGTEMPLATE *
102: CreateBusyTrayDialogTemplate
103: (
104: void
105: )
106: {
107: //
108: const DLGTEMPLATEITEMDATA items[] =
109: {
110: { CTLCLS_BUTTON, L"OK", WS_CHILD | BS_DEFPUSHBUTTON | WS_GROUP, 0, 0, 0, 1, 1, IDOK },
111: };
112:
113: //
114: DLGTEMPLATEHEAD dlg;
115: dlg.style = WS_POPUP | DS_SETFONT;
116: dlg.dwExtendedStyle = 0;
117: dlg.cdit = numof( items );
118: dlg.x = 0;
119: dlg.y = 0;
120: dlg.cx = 1,
121: dlg.cy = 1;
122: dlg.classname = null;
123: dlg.caption = L"";
124: dlg.menu = null;
125: dlg.font = L"MS Pゴシック";
126: dlg.height = 9;
127: ASSERT( IsValidDialogTemplateHead( &dlg ) );
128:
129: return CreateDialogTemplate( &dlg, items );
130: }//CreateBusyTrayDialogTemplate
131:
132:
133: //******************************************************************************************************************
134: //
135: //******************************************************************************************************************
136: static INT_PTR OnBusyTrayDlgInitDialog( HWND hWnd, LPARAM lParam );
137: static INT_PTR OnBusyTrayDlgDestroy( HWND hWnd );
138: static INT_PTR OnBusyTrayDlgIconMessage( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
139: static INT_PTR OnBusyTrayDlgCommand( HWND hWnd, WPARAM wParam, LPARAM lParam );
140: static INT_PTR OnBusyTrayDlgWindowPosChanging( HWND hWnd, LPARAM lParam );
141:
142:
143: //*********************************************************
144: // BusyTrayDlgProc
145: //*********************************************************
146: static
147: INT_PTR
148: CALLBACK
149: BusyTrayDlgProc
150: (
151: HWND hWnd,
152: UINT uMsg,
153: WPARAM wParam,
154: LPARAM lParam
155: )
156: {
157: // パラメタの仮定
158: ASSERT( IsValidWindow( hWnd ) );
159:
160: switch( uMsg )
161: {
162: case WM_INITDIALOG: return OnBusyTrayDlgInitDialog( hWnd, lParam );
163: case WM_DESTROY: return OnBusyTrayDlgDestroy( hWnd );
164: case WM_WINDOWPOSCHANGING: return OnBusyTrayDlgWindowPosChanging( hWnd, lParam );
165: case WM_COMMAND: return OnBusyTrayDlgCommand( hWnd, wParam, lParam );
166: case UM_ICONMESSAGE: return OnBusyTrayDlgIconMessage( hWnd, uMsg, wParam, lParam );
167: default: return false;
168: }
169: }//BusyTrayDlgProc
170:
171: //*********************************************************
172: // OnBusyTrayDlgInitDialog - WM_INITDIALOG
173: // ダイアログが作成された。
174: // この関数が抜けるまでダイアログは表示されない。
175: // 明示的にフォーカスを移動した場合は 真 を返す。
176: // さもなくば 偽 を返す。
177: // HWND wParam …… フォーカスを受け取る予定のコントロール
178: // LPARAM lParam …… ダイアログの初期化パラメタ
179: //*********************************************************
180: static
181: INT_PTR
182: OnBusyTrayDlgInitDialog
183: (
184: HWND hWnd,
185: LPARAM lParam
186: )
187: {
188: // パラメタの仮定
189: ASSERT( IsValidWindow( hWnd ) );
190: ASSERT( IsValidPtr( (busyicon_t *)lParam, sizeof( busyicon_t ) ) );
191:
192: //
193: const busyicon_t *bi = reinterpret_cast<busyicon_t *>( lParam );
194:
195: // スレッドの作成
196: thread_t *thread = CreateWorkerThread( bi->proc, bi->param );
197: VERIFY( SetProp( hWnd, PROP_THREAD, thread ) );
198: if ( ! thread )
199: {
200: ERROR_REPORT( "%s(%d) : %s \r\n", __FILE__, __LINE__,
201: "作業用スレッドの作成に失敗" );
202: EndDialog( hWnd, IDABORT );
203: return true;
204: }
205: ASSERT( IsValidWorkerThread( thread ) );
206:
207: // 作業中アイコンの登録
208: NOTIFYICONDATA *nid = AddWorkingTrayIcon( hWnd, ID_TRAYICON, UM_ICONMESSAGE, bi->hIcon, bi->message );
209: if ( !nid )
210: {
211: ERROR_REPORT( "%s(%d) : %s \r\n", __FILE__, __LINE__,
212: "作業中アイコンの登録に失敗" );
213: VERIFY( EndDialog( hWnd, IDABORT ) );
214: return true;
215: }
216: VERIFY( SetProp( hWnd, PROP_TRAYICON, nid ) );
217:
218: // キャンセル監視
219: if ( IDT_WAITTHREAD != SetTimer( hWnd, IDT_WAITTHREAD, 0, WatchWorkerThreadProc ) )
220: {
221: ERROR_REPORT( "%s(%d) : %s \r\n", __FILE__, __LINE__,
222: "キャンセル監視タイマの起動に失敗 - SetTimer( IDT_WAITTHREAD )" );
223: VERIFY( EndDialog( hWnd, IDABORT ) );
224: return true;
225: }
226:
227: // 実行開始
228: ResumeWorkerThread( thread );
229:
230: //
231: VisibleWindow( hWnd, false );
232:
233: return true;
234: }//OnBusyTrayDlgInitDialog
235:
236: //*********************************************************
237: // OnBusyTrayDlgDestroy - WM_DESTROY
238: // まもなくウィンドウが破棄される
239: // ウィンドウに関連付けた独自リソースを破棄する
240: // 常に 0L を返す
241: //*********************************************************
242: static
243: INT_PTR
244: OnBusyTrayDlgDestroy
245: (
246: HWND hWnd
247: )
248: {
249: // パラメタの仮定
250: ASSERT( IsValidWindow( hWnd ) );
251:
252: // タイマの停止
253: KillTimer( hWnd, IDT_WAITTHREAD );
254:
255: // 作業中アイコンを破棄する
256: NOTIFYICONDATA *nid = (NOTIFYICONDATA *)RemoveProp( hWnd, PROP_TRAYICON );
257: if ( nid )
258: {
259: VERIFY( DeleteNotifyIcon( nid ) );
260: free( nid );
261: }
262:
263: // スレッドを破棄する
264: thread_t *thread = (thread_t *)RemoveProp( hWnd, PROP_THREAD );
265: if ( thread )
266: {
267: VERIFY( DestroyWorkerThread( thread ) );
268: }
269:
270: return 0L;
271: }//OnBusyTrayDlgDestroy
272:
273: //*********************************************************
274: // OnBusyTrayDlgWindowPosChanging
275: //*********************************************************
276: static
277: INT_PTR
278: OnBusyTrayDlgWindowPosChanging
279: (
280: HWND hWnd,
281: LPARAM lParam
282: )
283: {
284: // パラメタの仮定
285: ASSERT( IsValidWindow( hWnd ) );
286: ASSERT( IsValidPtr( (WINDOWPOS *)lParam, sizeof( WINDOWPOS ) ) );
287:
288: //
289: WINDOWPOS *wpos = reinterpret_cast<WINDOWPOS *>( lParam );
290: wpos->flags &= ~SWP_SHOWWINDOW;
291: wpos->flags |= SWP_HIDEWINDOW;
292:
293: return false;
294: }//OnBusyTrayDlgWindowPosChanging
295:
296: //*********************************************************
297: // OnBusyTrayDlgIconMessage
298: //*********************************************************
299: static
300: INT_PTR
301: OnBusyTrayDlgIconMessage
302: (
303: HWND hWnd,
304: UINT ,
305: WPARAM wParam,
306: LPARAM lParam
307: )
308: {
309: // パラメタの仮定
310: ASSERT( IsValidWindow( hWnd ) );
311: ASSERT( IsValidWorkerThread( GetPropWorkerThread( hWnd ) ) );
312: ASSERT( ID_TRAYICON == wParam );
313:
314: if ( ID_TRAYICON != wParam )
315: {
316: return false;
317: }
318:
319: switch( lParam )
320: {
321: case WM_LBUTTONUP: { PostCommand( hWnd, UM_MENUPOPUP ); return false; }
322: case WM_RBUTTONUP: { PostCommand( hWnd, UM_MENUPOPUP ); return false; }
323: default: return false;
324: }
325: }//OnBusyTrayDlgIconMessage
326:
327:
328: //******************************************************************************************************************
329: //
330: //******************************************************************************************************************
331: static INT_PTR OnBusyTrayDlgCommandPopupMenu( HWND hWnd );
332: static INT_PTR OnBusyTrayDlgCommandCancel( HWND hWnd );
333:
334:
335: //*********************************************************
336: // OnBusyTrayDlgCommand - WM_COMMAND
337: // コマンド項目が選択された
338: // 返値の意味は要求されたコマンドの種類による
339: // LOWORD(wParam) …… 選択されたコマンド項目の識別子
340: // メニューの区切り線が選択された場合は 0 が設定される
341: // HIWORD(wParam) …… 通知コード
342: // メッセージが メニュー から送信された場合は 0 が設定される
343: // メッセージがアクセラレータから送信された場合は 1 が設定される
344: // HWND lParam …… メッセージがコントロールから送信された場合はメッセージを送信したコントロールのハンドル
345: //*********************************************************
346: static
347: INT_PTR
348: OnBusyTrayDlgCommand
349: (
350: HWND hWnd,
351: WPARAM wParam,
352: LPARAM _unuse( lParam )
353: )
354: {
355: // パラメタの仮定
356: ASSERT( IsValidWindow( hWnd ) );
357: ASSERT( IsValidCommandMessageParam( wParam, lParam ) );
358: ASSERT( IsValidWorkerThread( GetPropWorkerThread( hWnd ) ) );
359:
360: switch ( LOWORD(wParam) )
361: {
362: case UM_MENUPOPUP: return OnBusyTrayDlgCommandPopupMenu( hWnd );
363: case IDM_CANCEL: return OnBusyTrayDlgCommandCancel( hWnd );
364: default: return false;
365: }
366: }//OnBusyTrayDlgCommand
367:
368: //*********************************************************
369: // OnBusyTrayDlgCommandCancel
370: //*********************************************************
371: static
372: INT_PTR
373: OnBusyTrayDlgCommandCancel
374: (
375: HWND hWnd
376: )
377: {
378: // パラメタの仮定
379: ASSERT( IsValidWindow( hWnd ) );
380: ASSERT( IsValidWorkerThread( GetPropWorkerThread( hWnd ) ) );
381:
382: thread_t *thread = GetPropWorkerThread( hWnd );
383: VERIFY( CancelWorkerThread( thread ) );
384:
385: return false;
386: }//OnBusyTrayDlgCommandCancel
387:
388: //*********************************************************
389: // OnBusyTrayDlgCommandPopupMenu
390: //*********************************************************
391: static
392: INT_PTR
393: OnBusyTrayDlgCommandPopupMenu
394: (
395: HWND hWnd
396: )
397: {
398: // パラメタの仮定
399: ASSERT( IsValidWindow( hWnd ) );
400: ASSERT( IsValidWorkerThread( GetPropWorkerThread( hWnd ) ) );
401:
402: HMENU hmenuPopup = CreatePopupMenu();
403: if ( hmenuPopup )
404: {
405: //
406: VERIFY( AppendMenu( hmenuPopup, MFT_STRING, IDM_CANCEL, "キャンセル" ) );
407:
408: //
409: PopupMenuCursorPos
410: (
411: hWnd,
412: hmenuPopup,
413: TPM_RIGHTBUTTON | TPM_VERTICAL
414: );
415:
416: //
417: VERIFY( DestroyMenu( hmenuPopup ) );
418: }
419:
420: return false;
421: }//OnBusyTrayDlgCommandPopupMenu
422:
423:
424: //******************************************************************************************************************
425: //
426: //******************************************************************************************************************
427: //*********************************************************
428: // AddWorkingTrayIcon
429: //*********************************************************
430: static
431: NOTIFYICONDATA *
432: AddWorkingTrayIcon
433: (
434: HWND hWnd,
435: UINT uID,
436: UINT uMessage,
437: HICON hIcon,
438: const char *szTip
439: )
440: {
441: // パラメタの仮定
442: ASSERT( IsValidWindow( hWnd ) );
443: ASSERT( IsValidIconHandle( hIcon ) );
444: ASSERT( IsValidStringPtr( szTip ) );
445:
446: NOTIFYICONDATA *nid = CreateNotifyIconData
447: (
448: hWnd,
449: uID, // ID_ICON,
450: uMessage, // UM_ICONMESSAGE,
451: hIcon,
452: szTip // WAIT_MESSAGE
453: );
454: if ( !nid )
455: {
456: return null;
457: }
458:
459: VERIFY( AddNotifyIconRetry
460: (
461: nid,
462: 20,
463: 500
464: ) );
465:
466: return nid;
467: }//AddWorkingTrayIcon
468:
469:
470: //******************************************************************************************************************
471: //
472: //******************************************************************************************************************
473: //*********************************************************
474: // GetPropWorkerThread
475: //*********************************************************
476: static
477: thread_t *
478: GetPropWorkerThread
479: (
480: HWND hWnd
481: )
482: {
483: // パラメタの仮定
484: ASSERT( IsValidWindow( hWnd ) );
485:
486: thread_t *thread = (thread_t *)GetProp( hWnd, PROP_THREAD );
487: ASSERT( IsValidWorkerThread( thread ) );
488:
489: return thread;
490: }//GetPropWorkerThread
491:
492:
493: //******************************************************************************************************************
494: //
495: //******************************************************************************************************************
496: //*********************************************************
497: // WatchWorkerThreadProc
498: // スレッドの終了を監視する
499: // スレッドが終了したらウィンドウを閉じる
500: //*********************************************************
501: static
502: void
503: CALLBACK
504: WatchWorkerThreadProc
505: (
506: HWND hWnd,
507: UINT,
508: UINT uID,
509: DWORD
510: )
511: {
512: // パラメタの仮定
513: ASSERT( IsValidWindow( hWnd ) );
514: ASSERT( IsValidWorkerThread( GetPropWorkerThread( hWnd ) ) );
515:
516: // スレッドが終了していたらダイアログも終了
517: const thread_t *thread = GetPropWorkerThread( hWnd );
518: if ( IsWorkerThreadFinished( thread ) )
519: {
520: KillTimer( hWnd, uID );
521:
522: VERIFY( EndDialog( hWnd, IDOK ) );
523: }
524: }//WatchWorkerThreadProc
525:
526:
527: //** end **
528:
参照:
水無瀬の部屋 > sample > tools > workthrd > traythrd.cpp |
---|
このページは cpp2web が出力しました。
水無瀬 優 postmaster@katsura-kotonoha.sakura.ne.jp
http://katsura-kotonoha.sakura.ne.jp/prog/code/tools/workthrd/traythrd_cpp.shtml